package main

import (
	"encoding/json"
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	"io/ioutil"
	"log"
	"net/http"
	"strconv"
	"time"
	//"sync"
)

const urlPrefix = `http://sentence.iciba.com/index.php?&c=dailysentence&m=getdetail&sid=`

type sentenceInfo struct {
	Sid         int    `json:"sid"`
	Content     string `json:"content"`
	Note        string `json:"note"`
	Translation string `json:"translation"`
	Date        string `json:"title"`
}

type simpleInfo struct {
	ErrNo int `json:"errno"`
	sentenceInfo
}

type allContent struct {
	Data []sentenceInfo `json:"data"`
}

var data allContent

var errCount = 0

func checkContent(content *simpleInfo) bool {
	if content.ErrNo != 0 || content.Content == "test" || len(content.Content) < 10 {
		return false
	}
	return true
}

func getDailySentence(url string) {
	time.Sleep(10 * time.Microsecond)
	response, err := http.Get(url)
	if err != nil {
		log.Println(url, err)
		return
	}

	defer response.Body.Close()

	content := simpleInfo{}
	err = json.NewDecoder(response.Body).Decode(&content)
	if err != nil {
		data, _ := ioutil.ReadAll(response.Body)
		log.Println(url, data, response.Header, err)
		errCount++
		return
	}

	if checkContent(&content) {
		sentence := sentenceInfo{
			Sid:         content.Sid,
			Content:     content.Content,
			Note:        content.Note,
			Translation: content.Translation,
			Date:        content.Date,
		}
		data.Data = append(data.Data, sentence)
	} else {
		fmt.Printf("id[%d] errno[%d]\n", content.Sid, content.ErrNo)
	}
}

func getSentence(url string, in chan<- int) {
	time.Sleep(10 * time.Microsecond)
	response, err := http.Get(url)
	if err != nil {
		log.Println(url, err)
		in <- '1'
		return
	}

	defer response.Body.Close()

	content := simpleInfo{}
	err = json.NewDecoder(response.Body).Decode(&content)
	if err != nil {
		data, _ := ioutil.ReadAll(response.Body)
		log.Println(url, data, response.Header, err)
		errCount++
		in <- '1'
		return
	}

	if checkContent(&content) {
		sentence := sentenceInfo{
			Sid:         content.Sid,
			Content:     content.Content,
			Note:        content.Note,
			Translation: content.Translation,
			Date:        content.Date,
		}
		data.Data = append(data.Data, sentence)
	} else {
		fmt.Printf("id[%d] errno[%d]\n", content.Sid, content.ErrNo)
	}
	in <- '1'
}

const sheetName = "Sheet1"

func writeExcelFile() {
	file := excelize.NewFile()
	//file.NewSheet(sheetName)

	for k, v := range data.Data {
		//A1 1 B1 "hello" C1 "你好" D1 "你个傻子"
		col := k + 1
		a, b, c, d := "A"+strconv.Itoa(col), "B"+strconv.Itoa(col),
			"C"+strconv.Itoa(col), "D"+strconv.Itoa(col)
		file.SetCellValue(sheetName, a, v.Date)
		file.SetCellValue(sheetName, b, v.Content)
		file.SetCellValue(sheetName, c, v.Note)
		file.SetCellValue(sheetName, d, v.Translation)
	}
	err := file.SaveAs("result.xlsx")
	if err != nil {
		fmt.Println(err)
	}
}

const count = 3150

func main() {
	start := time.Now()

	for i := 1; i <= count; i++ {
		url := fmt.Sprintf("%s%d", urlPrefix, i)
		getDailySentence(url)
	}

	//实际测试发现，只有使用gorountine 服务端总会返回空数据
	//即使每个goroutine等待1second,依然会有问题
	//无奈一个一个等待，发顼3150个，也只是	366.34s
	/*in := make(chan int)

	for i := 1; i <= count; i++ {
		url := fmt.Sprintf("%s%d", urlPrefix, i)
		go getSentence(url, in)
	}

	for i := 1; i <= count; i++ {
		<-in
	}*/
	fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds())
	writeExcelFile()
}
